function SampleItem()
{
	//setting by user or ground truth
	this.centerX = 0;
	this.centerY = 0;
	this.groundTruthNormal = 0;  //vec3
	this.groundTruthPosition  = 0;  //vec3
	this.groundTruthSlantAngle = 0;
	this.groundTruthRotationAngle = 0;
	
	this.estimatedSlantAngle = 0;
	this.estimatedRotationAngle = 0;
}

SampleItem.prototype.setCenter = function(x, y)
{
	this.centerX = x;
	this.centerY = y;
	this.estimatedSlantAngle    = Math.random() * 90;
	this.estimatedRotationAngle = Math.random() * 360;			
}
SampleItem.prototype.setGroundTruthNormal = function(n)
{
	this.groundTruthNormal = n;
	this.estimatedSlantAngle =      (Math.PI - Math.acos(n.z)) * 180 /Math.PI;
	this.groundTruthRotationAngle = (Math.atan2(n.y, n.x) + Math.PI )* 180 /Math.PI;
}

SampleItem.prototype.setGroundTruthPosition = function (p)
{
	this.groundTruthPosition = p;
}

// adjust estimated slant and rotation angles with mouse movement
SampleItem.prototype.addSlant = function()
{
	this.estimatedSlantAngle += 2;
	if(this.estimatedSlantAngle > 80) //80 is extremely larger
	{
		this.estimatedSlantAngle = 80;
	}
}

SampleItem.prototype.decreaseSlant = function()
{
	this.estimatedSlantAngle -= 2;
	if(this.estimatedSlantAngle < -80)
	{
		this.estimatedSlantAngle = -80;
	}			
}
		
SampleItem.prototype.flipSlant = function()
{
	if(this.estimatedSlantAngle < 0)
	{
		this.estimatedSlantAngle = -this.estimatedSlantAngle;
	}
}	

SampleItem.prototype.setRotationAngleFromMousePosition = function(mx, my)
{
	//too close to center
	if(Math.abs( mx - this.centerX ) <= 2 && Math.abs( my - this.centerY ) <= 2)
	{					
		return ;
	}	
	var dx = mx - this.centerX;
	var dy = my - this.centerY;
	dy = -dy;            //coordinate of y is upside down

	var phi = Math.atan2(dy, dx) + Math.PI;
	this.estimatedRotationAngle = phi * 180/Math.PI;
}

SampleItem.prototype.getNormalWithSlant = function()
{
	return this.getNormal(0, 1);
}

SampleItem.prototype.getNormalWithRotation = function()
{
	return this.getNormal(1, 0);
}

SampleItem.prototype.getNormalFree = function()
{
	return this.getNormal(0, 0);
}





//output for rendering
SampleItem.prototype.getNormal = function(withGroudTruthRotationAngle, withGroundTruthSlantAngle)
{
//	assertTrue(this.estimatedRotationAngle >= -180 && this.estimatedRotationAngle <= 360);
//	assertTrue(this.estimatedSlantAngle >= -90 && this.estimatedSlantAngle <= 90);
	
	var slant = Math.PI - this.estimatedSlantAngle/180.0 * Math.PI;
	var rotation   = this.estimatedRotationAngle/180.0 * Math.PI;
	
	if(withGroudTruthRotationAngle)
	{
		rotation   = Math.atan2(this.groundTruthNormal[1], this.groundTruthNormal[0]) + Math.PI;				
	}
	if(withGroundTruthSlantAngle)
	{
		slant = Math.acos(this.groundTruthNormal[2]);				
	}
	
	var nx = Math.sin(slant) * Math.cos(rotation);
	var ny = Math.sin(slant) * Math.sin(rotation);
	var nz = Math.cos(slant);
	
	var n = vec3.fromValues(-nx, -ny, nz);			
	vec3.normalize(n, n);	
	return n;			
}
		
SampleItem.prototype.getPosition = function()
{
	return this.groundTruthPosition;
}			
SampleItem.prototype.getGroundTruthNormal = function()
{
	return this.groundTruthNormal;
}
